/*
 * @Description: 游戏控制器，控制其他所有类
 * @notes: 
 * @Author: 本火山
 * @Date: 2024-03-26 17:48:21
 * @LastEditors: 本火山
 * @LastEditTime: 2024-03-26 22:36:44
 */

// 引入其他类
import Snake from "./Snake";
import Food from "./Food";
import ScorePanel from "./ScorePanel";

class GameControl {
    // 定义三个属性
    // 蛇
    snake: Snake;
    food: Food;
    scorePanel: ScorePanel;
    // 创建一个属性来存储蛇的移动方向(也就是按键的方向)
    direction: string = "";
    // 创建一个属性用来记录游戏是否结束
    isLive: boolean = true;

    constructor() {
        this.snake = new Snake();
        this.food = new Food();
        this.scorePanel = new ScorePanel();
        this.init();
    }

    // 游戏初始化方法
    init() {
        // 绑定键盘按下事件
        document.addEventListener('keydown', this.keydownHandler.bind(this));// 如果不传递 this 就会指dom
        // 调用 run 方法使蛇移动
        this.run();
    }

    // 创建一个键盘按下的响应函数
    keydownHandler(event: KeyboardEvent) {
        /**
         * ArrowUp      Up
         * ArrowDown    Down
         * ArrowLeft    Left
         * ArrowRight   Right
         * 
         * 
        */
        //  需要检查 event.key 是否合法
        this.direction = event.key;
    }

    // 创建一个控制蛇移动的方法
    run() {
        /**
         *  根据方向(this.direction)来使蛇的位置改变
         *      向上 top 减少
         *      向下 top 增加
         *      向右 left 增加
         *      向左 left 减少
        */
        //    获取蛇现在坐标
        let X = this.snake.X;
        let Y = this.snake.Y;

        // 根据按键方向修改 X 值， Y 值
        switch (this.direction) {
            case "ArrowUp":
            case "Up":
                // 向上移动
                Y -= 10;
                break;
            case "ArrowDown":
            case "Down":
                // 向下移动
                Y += 10;
                break;
            case "ArrowLeft":
            case "Left":
                // 向左移动
                X -= 10;
                break;
            case "ArrowRight":
            case "Right":
                // 向右移动
                X += 10;
                break;
        }

        // 检查蛇是否吃到食物
        this.checkEat(X, Y);
        // 修改蛇的 X 值 和 Y值
        try {
            this.snake.Y = Y;
            this.snake.X = X;
        } catch (e: any) {
            // 进入到 catch,说明出现了异常，游戏结束，弹出一个提示信息
            alert(e.message);
            this.isLive = false;
        }

        // 开启定时调用
        this.isLive && setTimeout(this.run.bind(this), 300 - (this.scorePanel.level - 1) * 30)
    }

    // 定义一个方法，用来检测蛇是否吃到食物
    checkEat(X: number, Y: number): void {
        if (X === this.food.X && Y === this.food.Y) {
            // 食物的位置要进行重置
            this.food.change();
            // 分数增加
            this.scorePanel.addScore();
            // 蛇妖增加一节
            this.snake.addBody();
        } else {

        }
    }
}
export default GameControl;